package com.tansun.easycare.rule.utils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MIME;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.AbstractContentBody;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.Args;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
	 
/**
 * PyHttpUtil工具类 用于请求python服务
 * @author xch
 * @date 2018年8月15日 下午4:59
 */
public class PyHttpUtil {
		
	private final static Logger logger = LoggerFactory.getLogger(PyHttpUtil.class);
	 
		/**
		 * get请求
		 * @return
		 */
		public static String doGet(String url) {
	        try {
	        	HttpClient client = HttpClients.createDefault();
	            //发送get请求
	            HttpGet request = new HttpGet(url);
	            HttpResponse response = client.execute(request);
	 
	            /**请求发送成功，并得到响应**/
	            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
	                /**读取服务器返回过来的json字符串数据**/
	                String strResult = EntityUtils.toString(response.getEntity());
	                
	                return strResult;
	            }
	        } catch (IOException e) {
	        	e.printStackTrace();
	        }
	        
	        return null;
		}
		
		/**
		 * post请求(用于key-value格式的参数)
		 * @param url
		 * @param params
		 * @return
		 */
		@SuppressWarnings({ "deprecation" })
		public static String doPost(String url, Map<?, ?> params){
			
			BufferedReader in = null;  
	        try {  
	            // 定义HttpClient  
	        	CloseableHttpClient client = HttpClients.createDefault();  
	            // 实例化HTTP方法  
	            HttpPost request = new HttpPost();  
	            request.setURI(new URI(url));
	            
	            //设置参数
	            List<NameValuePair> nvps = new ArrayList<NameValuePair>(); 
	            for (Iterator<?> iter = params.keySet().iterator(); iter.hasNext();) {
	    			String name = (String) iter.next();
	    			String value = String.valueOf(params.get(name));
	    			nvps.add(new BasicNameValuePair(name, value));
	    			
	    			//System.out.println(name +"-"+value);
	    		}
	            request.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8));
	            
	            HttpResponse response = client.execute(request);  
	            int code = response.getStatusLine().getStatusCode();
	            if(code == 200){	//请求成功
	            	in = new BufferedReader(new InputStreamReader(response.getEntity().getContent(),"utf-8"));
	                StringBuffer sb = new StringBuffer("");  
	                String line = "";  
	                String NL = System.getProperty("line.separator");  
	                while ((line = in.readLine()) != null) {  
	                    sb.append(line + NL);  
	                }
	                in.close();  
	                
	                return sb.toString();
	            }else{
	            	//
	            	System.out.println("状态码：" + code);
	            	return null;
	            }
	        }catch(Exception e){
	        	e.printStackTrace();
	        	return null;
	        }
		}
		
		/**
		 * post请求（用于请求json格式的参数）
		 * @param url
		 * @param params
		 * @return
		 * @throws IOException 
		 * @throws ClientProtocolException 
		 */
		public static String doPost(String url, String params) throws ClientProtocolException, IOException {
			
			CloseableHttpClient httpclient = HttpClients.createDefault();
			HttpPost httpPost = new HttpPost(url);// 创建httpPost   
	    	httpPost.setHeader("Accept", "application/json"); 
	    	httpPost.setHeader("Content-Type", "application/json");
	    	String charSet = "UTF-8";
	    	StringEntity entity = new StringEntity(params, charSet);
	    	httpPost.setEntity(entity);        
	        CloseableHttpResponse response = null;
	        
	        try {
	        	
	        	response = httpclient.execute(httpPost);
	            StatusLine status = response.getStatusLine();
	            int state = status.getStatusCode();
	            if (state == HttpStatus.SC_OK) {
	            	HttpEntity responseEntity = response.getEntity();
	            	String jsonString = EntityUtils.toString(responseEntity);
	            	return jsonString;
	            }else{
					 logger.error("请求返回:"+state+"("+url+")");
				}
	        }finally {
	            if (response != null) {
	                try {
	                    response.close();
	                } catch (IOException e) {
	                    e.printStackTrace();
	                }
	            }
	            try {
					httpclient.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
	        }
	        return null;
		}
		/**
		 * post请求（用于下载文件）
		 * @param url
		 * @param params
		 * @return
		 * @throws IOException 
		 * @throws ClientProtocolException 
		 */
		public static byte[] doPostDownload(String url, String savepath) throws ClientProtocolException, IOException {
			InputStream in = doPostDownloadByStream(url, savepath);
			byte[] res = PyHttpUtil.input2byte(in);
	        return res;
		}
		
		/**
		 * post请求（用于下载文件）
		 * @param url
		 * @param params
		 * @return
		 * @throws IOException 
		 * @throws ClientProtocolException 
		 */
		public static InputStream doPostDownloadByStream(String url, String savepath) throws ClientProtocolException, IOException {
			CloseableHttpClient httpClient = HttpClients.createDefault();
			
//			HttpGet httpGet = new HttpGet(url+"?savepath="+savepath);
//			httpGet.addHeader("savepath", savepath);
//			HttpResponse response = httpClient.execute(httpGet);
			HttpPost httpPost = new HttpPost(url);// 创建httpPost   
	    	httpPost.setHeader("Accept", "application/json"); 
	    	httpPost.setHeader("Content-Type", "application/json");
	    	String charSet = "UTF-8";
	    	JSONObject reqjson = new JSONObject();
	    	reqjson.put("savepath", savepath);
	    	StringEntity reqentity = new StringEntity(reqjson.toJSONString(), charSet);
	    	httpPost.setEntity(reqentity); 
			HttpResponse response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			InputStream in = entity.getContent();
	        return in;
		}
		/**
		 * 输入流转byte
		 * @param inStream
		 * @return
		 * @throws IOException
		 */
		private static final byte[] input2byte(InputStream inStream) throws IOException {
			ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
			byte[] buff = new byte[100];
			int rc = 0;
			while ((rc = inStream.read(buff, 0, 100)) > 0) {
				swapStream.write(buff, 0, rc);
			}
			byte[] in2b = swapStream.toByteArray();
			return in2b;
		}
		/**
		 * post请求（用于上传文件格式）
		 * @param url
		 * @param localFile 文件名
		 * @param savepath 保存位置
		 * @param apply 文件的作用
		 * @return String 返回json字符串
		 * @throws IOException 
		 * @throws ClientProtocolException 
		 */
		public static String uploadPost(String datapath,String modelId, String apply, String url) throws ClientProtocolException, IOException{

            File file = new File(datapath);
            FileBody fileBody = new FileBody(file);
            StringBody modelIdBody = new StringBody(modelId, ContentType.create("text/plain", Consts.UTF_8));
            StringBody applyBody = new StringBody(apply, ContentType.create("text/plain", Consts.UTF_8));
            
            MultipartEntityBuilder entity=MultipartEntityBuilder.create();
            entity.addPart("file", fileBody);
            entity.addPart("modelId", modelIdBody);
            entity.addPart("apply", applyBody);
            
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(entity.build());
            
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpResponse response = httpClient.execute(httpPost);
	       
            int state = response.getStatusLine().getStatusCode();
            if (state == HttpStatus.SC_OK) {
            	HttpEntity responseEntity = response.getEntity();
            	String jsonString = EntityUtils.toString(responseEntity);
            	return jsonString;
            }else{
				 logger.error("请求返回:"+state+"("+url+")");
			}
            return null;
		}
		/**
		 * post请求（用于上传文件格式）
		 * @param url 地址
		 * @param inputMap 传输信息
		 * @return String 返回json字符串
		 * @throws IOException 
		 * @throws ClientProtocolException 
		 */
		public static String uploadPost(File file,Map<String,String> inputMap, String url) throws ClientProtocolException, IOException{

            FileBody fileBody = new FileBody(file);
            MultipartEntityBuilder entity=MultipartEntityBuilder.create();
            entity.addPart("file", fileBody);
            
            for(String key:inputMap.keySet()){
            	String value = inputMap.get(key);
            	StringBody strBody = new StringBody(value, ContentType.create("text/plain", Consts.UTF_8));
	            entity.addPart(key, strBody);
            }
            
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(entity.build());
            
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpResponse response = httpClient.execute(httpPost);
	       
            int state = response.getStatusLine().getStatusCode();
            if (state == HttpStatus.SC_OK) {
            	HttpEntity responseEntity = response.getEntity();
            	String jsonString = EntityUtils.toString(responseEntity);
            	return jsonString;
            }else{
				 logger.error("请求返回:"+state+"("+url+")");
			}
            return null;
		}
		
		/**
		 * post请求（用于上传文件格式）
		 * @param url 地址
		 * @param inputMap 传输信息
		 * @return String 返回json字符串
		 * @throws IOException 
		 * @throws ClientProtocolException 
		 */
		public static String uploadPost(InputStream inStream,String filename,Map<String,String> inputMap, String url) throws ClientProtocolException, IOException{
			byte[] byteArr  = input2byte(inStream);
            return uploadPost(byteArr,filename,inputMap,url);
		}
		
		/**
		 * post请求（用于上传文件格式）
		 * @param url 地址
		 * @param inputMap 传输信息
		 * @return String 返回json字符串
		 * @throws IOException 
		 * @throws ClientProtocolException 
		 */
		public static String uploadPost(byte[] byteArr,String filename,Map<String,String> inputMap, String url) throws ClientProtocolException, IOException{

			ByteArrayBody byteArrayBody = new ByteArrayBody(byteArr,filename);
            MultipartEntityBuilder entity=MultipartEntityBuilder.create();
            entity.addPart("file", byteArrayBody);
            
            for(String key:inputMap.keySet()){
            	String value = inputMap.get(key);
            	StringBody strBody = new StringBody(value, ContentType.create("text/plain", Consts.UTF_8));
	            entity.addPart(key, strBody);
            }
            
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(entity.build());
            
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpResponse response = httpClient.execute(httpPost);
	       
            int state = response.getStatusLine().getStatusCode();
            if (state == HttpStatus.SC_OK) {
            	HttpEntity responseEntity = response.getEntity();
            	String jsonString = EntityUtils.toString(responseEntity);
            	return jsonString;
            }else{
				 logger.error("请求返回:"+state+"("+url+")");
			}
            return null;
		}
		
		public static void main(String[] args) throws ClientProtocolException, IOException{
			String str = "http://127.0.0.1:8889/upload";
			String local = "D://files/dst.csv";
			uploadPost(local,"72","train",str);
		}
}
class PyFileBody extends AbstractContentBody {

    private final File file;
    private final String filename;
    private final byte[] byteArr;

    /**
     * @since 4.1
     *
     * @deprecated (4.3) use {@link FileBody#FileBody(File, ContentType, String)}
     *   or {@link org.apache.http.entity.mime.MultipartEntityBuilder}
     */
    @Deprecated
    public PyFileBody(final File file,
                    final String filename,
                    final String mimeType,
                    final String charset) {
        this(file, ContentType.create(mimeType, charset), filename);
    }

    /**
     * @since 4.1
     *
     * @deprecated (4.3) use {@link FileBody#FileBody(File, ContentType)}
     *   or {@link org.apache.http.entity.mime.MultipartEntityBuilder}
     */
    @Deprecated
    public PyFileBody(final File file,
                    final String mimeType,
                    final String charset) {
        this(file, null, mimeType, charset);
    }

    /**
     * @deprecated (4.3) use {@link FileBody#FileBody(File, ContentType)}
     *   or {@link org.apache.http.entity.mime.MultipartEntityBuilder}
     */
    @Deprecated
    public PyFileBody(final File file, final String mimeType) {
        this(file, ContentType.create(mimeType), null);
    }

    public PyFileBody(final File file) {
        this(file, ContentType.DEFAULT_BINARY, file != null ? file.getName() : null);
    }
    
    public PyFileBody(final byte[] byteArr) {
    	super(ContentType.DEFAULT_BINARY);
    	this.file = null;
        this.filename = null;
    	this.byteArr = byteArr;
    }

    /**
     * @throws FileNotFoundException 
     * @since 4.3
     */
    public PyFileBody(final File file, final ContentType contentType, final String filename) {
        super(contentType);
        Args.notNull(file, "File");
        this.file = file;
        this.filename = filename == null ? file.getName() : filename;
		this.byteArr = null;
    }

    /**
     * @since 4.3
     */
    public PyFileBody(final File file, final ContentType contentType) {
        this(file, contentType, file != null ? file.getName() : null);
    }

    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(this.byteArr);
    }

    @Override
    public void writeTo(final OutputStream out) throws IOException {
        Args.notNull(out, "Output stream");
        final InputStream in = new ByteArrayInputStream(this.byteArr);
        try {
            final byte[] tmp = new byte[4096];
            int l;
            while ((l = in.read(tmp)) != -1) {
                out.write(tmp, 0, l);
            }
            out.flush();
        } finally {
            in.close();
        }
    }

    @Override
    public String getTransferEncoding() {
        return MIME.ENC_BINARY;
    }

    @Override
    public long getContentLength() {
    	if (this.file==null){
    		return this.byteArr.length;
    	}else{
    		return this.file.length();
    	}
    }

    @Override
    public String getFilename() {
        return filename;
    }

    public File getFile() {
        return this.file;
    }

}
